﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace SampleDataTools
{
    public class WorkItem
    {
        public ItemConfig Item { get; set; }
        public BuffData LastDataWriteToFile { get; private set; }

        private readonly List<BuffData> Buffs = new List<BuffData>();
        private FileStream fileStream;
        private StreamWriter StreamWriter;
        private UdpClient udpClient;
        private IPEndPoint point;

        public void Open()
        {
            udpClient = new UdpClient(Item.Port);
            udpClient.Client.Blocking = false;

            point = new IPEndPoint(IPAddress.Any, 0);

            if (Item.WriteType == WriteType.Byte)
            {
                fileStream = File.Create(Item.WriteFileName);
            }
            else
            {
                StreamWriter = File.CreateText(Item.WriteFileName);
            }
        }

        public void Receive()
        {
            if (udpClient?.Available > 0)
            {
                var buff = udpClient.Receive(ref point);
                if (buff.Length == Item.Count * (Item.Type == DataType.Double ? 8 : 4))
                {
                    Buffs.Add(new BuffData(Item) { Buffs = buff });
                }
            }
        }

        public bool WriteToFile()
        {
            bool available = false;
            if (Buffs.Count != 0)
            {

                var buff = Buffs[0];
                if (buff == null)
                {
                    return false;
                }
                LastDataWriteToFile = buff;
                Buffs.RemoveAt(0);

                if (Item.WriteType == WriteType.Byte)
                {
                    fileStream?.Write(buff.Buffs, 0, buff.Buffs.Length);
                }
                else
                { 
                    string mask = Item.DataFormat == DataFormat.E ? "{0:E} " : "{0:F} ";
                    for (int i = 0; i < Item.Count; i++)
                    {
                        StreamWriter?.Write(mask, buff.GetValue(i));
                    }
                    StreamWriter.WriteLine();
                }

                available = true;
            }
            return available;
        }

        public void Close()
        {
            if (fileStream != null)
            {
                fileStream.Close();
            }
            if (StreamWriter != null)
            {
                StreamWriter.Close();
            }
            if (udpClient != null)
            {
                udpClient.Close();
            }
            fileStream = null;
            StreamWriter = null;
            udpClient = null;
            point = null;
        }

        public void CopyToDirectory(string dir)
        {
            if (!Directory.Exists(dir))
            {
                Directory.CreateDirectory(dir);
            }
            try
            {
                File.Copy(Item.WriteFileName, dir + "//" + Item.WriteFileName,true);
            }
            catch (Exception)
            {
            }
        }
    }
}
